<?php

namespace App\Http\Controllers;

use App\Models\SwtFileAnalyse;
use App\Models\SwtFileAnalyseChat;
use App\Services\AliyunService;
use Dingo\Api\Http\Response;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use OSS\Core\OssException;
use OSS\Http\RequestCore_Exception;
use OSS\OssClient;

class CeshiController extends BaseController
{
    /**
     * 提交文件
     * @param Request $request
     * @return Response
     */
    public function uploadFile(Request $request): Response
    {
        $file=$request->file('file');
        $filename = $file->getClientOriginalName();
        $filepath = $file->getRealPath();

        $suffix = explode('.',$filename);
        $pathName = 'upload/File/' . date('Y-m') . '/' . uniqid() . '.' . $suffix[1]; //生成文件名
        $filePath = $filepath; //临时文件路基

        $config = [
            'accessId'=>config('services.oss.accessKeyId'),
            'accessKey'=>config('services.oss.accessKeySecret'),
            'endpoint'=>env('ALI_OSS_ENDPOINT'),
            'bucket'=> env('ALI_OSS_BUCKET_NAME'),
        ];
        $ossClient = new OssClient($config['accessId'], $config['accessKey'], $config['endpoint']);


        $result = $ossClient->uploadFile($config['bucket'], $pathName, $filePath);

        if(!empty($result['info']['url'])){
            $ali = new AliyunService();
            $file_url = $result['info']['url'];
            $name = explode('/',$file_url);
            foreach($name as $v){
                if(strstr($v,$suffix[1])){
                    $file_name = $v;
                }
            }
            $res = $ali->submitDocToAliyun($file_url,$file_name);
            // var_dump($res);
            $swt_file = SwtFileAnalyse::create(['file_res_id'=>$res['body']['data']['id'],'res_json'=>json_encode($res),'status'=>1,'file_url'=>$result['info']['url'],'file_name'=>$filename,'object_name'=>$pathName]);
            return $this->success($swt_file,'上传成功');
        }
        return $this->success([],'上传失败');

    }

    /**
     * OCR 返回数据
     */
    public function ocrFile(Request $request){
        $file_id = $request->input('id');
        $file_data = SwtFileAnalyse::where('id',$file_id)->first();
        $ali = New AliyunService();


        if(empty($file_data)){
            return $this->error([],'数据不存在');
        }

        if( $file_data->status == 2){
            return $this->success(['content'=>$file_data->gpt_res,'json'=>json_decode($file_data->analyse_res)]);
        }
        //查询文档解析进度
        $query_data = $ali->queryDocToAli($file_data->file_res_id);
        if(in_array($query_data['body']['data']['status'],['Processing','Init'])){
            return $this->error([],'文档解析还未完成，请稍后再试');
        }
        //获取文档解析结构
        $res_data = $ali->getDocResForAli($file_data->file_res_id,$query_data['body']['data']['numberOfSuccessfulParsing']);
        $body = '';
        if(empty($res_data['body']['data']['layouts'])){
            $msg = self::errorEnums($res_data['body']['code']);
            return $this->error([],$msg);
        }
        $text_num = 0;
        $table_num = [];
        //组装请求数组
        foreach($res_data['body']['data']['layouts'] as $v){
            //单独处理表格部分
            if($v['type'] == 'table'){
                if(in_array($v['pageNum'],$table_num)){
                    continue;
                }
                //创建格式转换任务
                $result = $ali->createOfficeConversionTask($v['pageNum'], $file_data->object_name, $file_data->file_name);
                sleep(1);
                //转换任务的结果
                again:
                $res = $ali->getTask($result['body']['taskId']);
                if($res['body']['status'] == 'Succeeded'){

                    $new_file_name = explode('.',$file_data->file_name);
                    $new_file = $new_file_name[0].'.jpg';

                    //转换后的图片要进行文字识别
                    $text_res = $ali->DetectImageText($new_file);
                    foreach($text_res['body']['OCRContents'] as $text_v){
                        $body.=$text_v['contents'].",\t";
                    }

                    $table_num[] = $v['pageNum'];
                }else{
                    sleep(1);
                    goto again;
                }
            }
            if($v['type']  == 'text'){
                //非表格就直接拼接
                if($text_num == $v['pageNum']){
                    $body .= $v['text'];
                }else{
                    $body .= "<br/><br/><br/>".$v['text'];
                    $text_num++;
                }
            }

        }
        $file_data->update(['analyse_res'=>json_encode($body),'analyse_json'=>json_encode($res_data),'status'=>2]);

        return $this->success([],'文件解析识别成功');
    }

    public function showFile(){
        $file_list = SwtFileAnalyse::select(['id','file_name','created_at'])->orderBy('id','desc')->get()->toArray();

        return $this->success($file_list);
    }

    //给GPT发初始消息
    public function firstSendMsg(Request $request){
        $id = $request->input('id');
        $file_data = SwtFileAnalyse::where('id',$id)->first();

        $body = json_decode($file_data->analyse_res,true);
        DB::beginTransaction();
        try {
            //请求gpt代理 获取精简后结果
            $url = 'http://103.118.244.75:3090/v1/chat/completions';
            $data = [
                "model" => "gpt-4o",
                "messages" =>[[
                    "role"=>"system",
                    "content"=>"You are Good at handling text and summarizing!",
                    "unset"=>1
                ],[
                    'role'=>'user',
                    'content'=>$body
                ],[
                    'role'=>'user',
                    'content'=>"（提取公司（项目）名称，公司（项目）简介）：重点保留控股母公司，投融资情况，荣誉资质、业务发展情况等相关信息",
                    "unset"=>1
                ],[
                    'role'=>'user',
                    'content'=>"（提取技术要点，技术指标，技术水平）：重点保留项目的突出优势和项目的价格优势以及整体的先进水平",
                    "unset"=>1
                ],[
                    'role'=>'user',
                    'content'=>'提取适用行业，市场规模（要展示具体数字），融资要求，发展规划（要具体到年份）',
                    "unset"=>1
                ],[
                    'role'=>'user',
                    'content'=>'（展示团队信息，展示联系号码）：要提取到所有人员',
                    "unset"=>1
                ],[
                    'role'=>'user',
                    'content'=>'根据以上总结信息，查询该公司和所在行业的中国行业数据，并全量展示',
                    "unset"=>1
                ]]
            ];

            foreach($data['messages'] as $k=>$v){
                if(isset($v['unset'])){continue;}
                if($v['role'] == 'user'){
                    $chat_data = [
                        'chat_id' => $id,
                        'role'=> 2,
                        'content'=>$v['content'],
                        'created_at'=>date('Y-m-d H:i:s')
                    ];
                    SwtFileAnalyseChat::create($chat_data);
                }else{
                    $chat_data = [
                        'chat_id' => $id,
                        'role'=> 1,
                        'content'=>$v['content'],
                        'created_at'=>date('Y-m-d H:i:s')
                    ];
                    SwtFileAnalyseChat::create($chat_data);
                }

            }

            //curl gpt
            $result = $this->gpt_curl($url,$data);

            $file_data->update(['gpt_id'=>$result['id']]);
            SwtFileAnalyseChat::create(['chat_id'=>$id,'role'=>1,'content'=>$result['choices'][0]['message']['content'],'created_at'=>date('Y-m-d H:i:s')]);

            if (!$result) {
                DB::rollBack();
                throw new \Exception($result['message'] ?? '请求GPT接口存在异常');
            }
            DB::commit();

            $chat = SwtFileAnalyseChat::where('chat_id',$file_data->id)->get()->toArray();
            return $this->success($chat);
        }catch (\Exception $exception){
            DB::rollBack();
            return $this->error($exception -> getMessage(), $exception -> getCode());
        }

    }

    public function send_msg(Request $request){
        $id = $request->input('id');
        $content = $request->input('content');
        $file_data = SwtFileAnalyse::find($id);
        $chat = SwtFileAnalyseChat::where('chat_id',$file_data->id)->get()->toArray();
        $message = [];
        foreach($chat as $k=>$v){
            $message[] = [
                'role' => $v['role'] == 1 ? 'system' : 'user',
                'content' => $v['content'],
            ];
        }
        array_push($message,['role'=>'user','content'=>$content]);
        $data = [
            "id"=>"$file_data->id",
            "model" => "gpt-4o",
            "object"=> "chat.completion",
            "messages" => $message,
        ];
        $create_data = [
            'chat_id'=>$file_data->id,
            'role'=>2,
            'content'=>$content,
            'created_at'=>date('Y-m-d H:i:s')
        ];
        SwtFileAnalyseChat::create($create_data);
        $url = 'http://103.118.244.75:3090/v1/chat/completions';
        $result = $this->gpt_curl($url,$data);
        $new_chat = ['chat_id'=>$file_data->id,
            'role'=>1,
            'content'=>$result['choices'][0]['message']['content'],
            'created_at'=>date('Y-m-d H:i:s')];
        SwtFileAnalyseChat::create($new_chat);
        return $this->success($new_chat);
    }

    public function show_file_content(Request $request){
        $id = $request->input('id');
        $chat = SwtFileAnalyseChat::where('chat_id',$id)->get()->toArray();
        return $this->success($chat);
    }

    public function gpt_curl($url,$data){
        $ch = curl_init();
        $header = ['Content-Type:application/json','Authorization: Bearer sk-lh8OwY5e3NzyciNjB0BbD88e70Ee4b2fBdEcC5B758314fF2'];
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        $result = json_decode(curl_exec($ch), true);
        return $result;
    }


    public static function errorEnums($code){
        $error = [
            'SystemError'=>'系统异常，请稍后重试。',
            'ServiceTimeout'=>'服务超时，请稍后重试。',
            'AlgorithmError'=>'算法服务异常，请稍后重试。',
            'DocProcessing'=>'文档处理中，请等待处理完成。',
            'NotSupportFormat'=>'文档格式不支持。',
            'FileUrlLegal'=>'文件URL不合法。',
            'MissingFileUrl'=>'文件URL不能为空。',
            'MissingId'=>'业务ID不能为空。',
            'ExceededImageUrlLength'=>'文档URL长度超过限制。',

            'ExceededImageUrlSize'=>'图片URL数量超过限制',

            'FileSizeNotEqual'=>'文件名称数量与文件URL数量不一致',

            'NotSpecifySuffix'=>'未指定文件后缀',

            'FileNameLegal'=>'文档名称不合法',

            'NotExistBizId'=>'业务ID不存在',

            'IllegalApiName'=>'API名称不合法',

            'IllegalSignature'=>'签名错误',

            'InvalidStsToken'=>'STS token 错误。',

            'DocMindServiceNotOpen'=>'文档智能服务未开通',

            'DocMindServiceExpired'=>'文档智能服务已过期',

            'NoPermission'=>'请检查服务是否正确开通',

            'Failed'=>'文档处理失败',

            'ParamsError'=>'文档处理请求参数有误(支持格式：pdf、word、ppt、pptx、xls、xlsx、xlsm)',

            'DocDownloadError'=>'文档处理过程中数据下载异常，请检查文档是否能访问和下载。',

            'InterfaceMismatch'=>'您当前请求的结果查询接口和该ID生成的异步提交接口并不匹配，请检查接口后重试。',

            'BlankDocError'=>'文档内容为空。'
        ];
        return $error[$code];
    }
}
